package com.app.business.web.business.property;

import com.app.business.calculate.CalculateUtils;
import com.app.business.en.Status;
import com.app.business.model.CarLot;
import com.app.business.model.Contract;
import com.app.business.model.House;
import com.app.business.model.StorageRoom;
import com.app.business.service.*;
import com.app.business.utils.AreaAndPriceUtils;
import com.app.business.utils.CareBuyAreaUtils;
import com.app.system.jpa.PageBean;
import com.app.system.log4j2.LogUtils;
import com.app.system.permission.model.DataDict;
import com.app.system.permission.service.DataDictService;
import com.app.system.utils.CollectionUtils;
import com.app.system.utils.ParamUtils;
import com.app.system.utils.WebUtils;
import com.app.system.utils.dataType.BigDecimalUtils;
import com.app.system.utils.dataType.DateUtils;
import com.app.system.utils.dataType.IntegerUtils;
import com.app.system.utils.dataType.StringUtils;
import com.app.system.utils.exception.Precondition;
import com.app.system.utils.exception.Response;
import com.app.system.utils.page.LayUiUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import freemarker.template.Configuration;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 契税业务层
 * Created by ddz on 2021/11/3.
 */
@Controller
@RequestMapping("/business/property/deedTax/*")
@SuppressWarnings("all")
public class DeedTaxController {
    @Autowired
    private ContractService contractService;
    @Autowired
    private DataDictService dataDictService;
    @Autowired
    private HouseService houseService;
    @Autowired
    private CarLotService carLotService;
    @Autowired
    private StorageRoomService storageRoomService;
    @Autowired
    private BuyHousePersonService buyHousePersonService;
    @Autowired
    private Configuration freemarkerConfiguration; // 注入bean，这里是属性注入，推荐构造注入
    private Logger logger = LogUtils.getBusinessLogger();

    /**
     * 协议
     * 契税数据管理列表
     */
    @RequestMapping("deedTaxList")
    @RequiresPermissions("deedTax:deedTaxList")
    public void deedTaxList() {
    }

    /**
     * 加载基础信息数据
     * 协议
     *
     * @return
     */
    @RequestMapping("loadDeedTaxList")
    @ResponseBody
    @RequiresPermissions("deedTax:loadDeedTaxList")
    public Map loadDeedTaxList() {
        List<Map> listData = Lists.newArrayList();
        PageBean<Contract> contractPageBean = this.contractService.getChoosedHousePageBean();
        List<Contract> contractList = contractPageBean.getDatas();
        Map<String, DataDict> groupMap = this.dataDictService.getMapByParentNameForValue("组别");
        Map<String, DataDict> signMap = this.dataDictService.getMapByParentNameForValue("签约状态");
        Map<String, DataDict> checkMap = this.dataDictService.getMapByParentNameForValue("复核状态");
        Map<String, DataDict> chooseHouseMap = this.dataDictService.getMapByParentNameForValue("房源签认状态");
        Map<String, DataDict> isAndNoMap = this.dataDictService.getMapByParentNameForValue("是否");

        if (CollectionUtils.isNotEmpty(contractList)) {
            Map<String, Object> item = null;
            for (Contract contract : contractList) {
                item = null;
                item = Maps.newHashMap();
                item.put("id", contract.getId());
                item.put("zsProjectName", StringUtils.getNotNull(contract.getZsProject().getProjectName()));
                item.put("groupCode", StringUtils.dataDictShow(groupMap.get(contract.getGroupCode())));
                item.put("contractCode", StringUtils.getNotNull(contract.getContractCode()));
                item.put("name", StringUtils.getNotNull(contract.getName()));
                item.put("chooseHouseNum", StringUtils.getNotNull(contract.getChooseHouseNum()));
                item.put("preChooseDate", DateUtils.dateToStringDefault(contract.getPreChooseDate()));
                item.put("limitHouseAreaTotal", BigDecimalUtils.getNotNullStr(contract.getLimitHouseAreaTotal()));
                item.put("chooseHouseStatus", IntegerUtils.getNotNull(contract.getChooseHouseStatus()));
                item.put("chooseHouseStatusStr", StringUtils.dataDictShow(chooseHouseMap.get(IntegerUtils.getNotNull(contract.getChooseHouseStatus()).toString())));
                item.put("azSignStatus", IntegerUtils.getNotNull(contract.getAzSignStatus()));
                item.put("limitStatus", IntegerUtils.getNotNull(contract.getLimitStatus()));
                item.put("limitStatusStr", StringUtils.dataDictShow(isAndNoMap.get(IntegerUtils.getNotNull(contract.getLimitStatus()).toString())));
                item.put("azSignStatusStr", StringUtils.dataDictShow(signMap.get(IntegerUtils.getNotNull(contract.getAzSignStatus()).toString())));
                item.put("financeCheckStatus", IntegerUtils.getNotNull(contract.getFinanceCheckStatus()));
                item.put("financeCheckStatusStr", StringUtils.dataDictShow(checkMap.get(IntegerUtils.getNotNull(contract.getFinanceCheckStatus()).toString())));
                listData.add(item);
            }
        }
        return LayUiUtils.page(contractPageBean.getTotalCount().intValue(), listData);
    }

    /**
     * 契税情况表，四方会签表
     *
     * @param request
     * @param modelMap
     */
    @RequestMapping("deedTaxPrint")
    @RequiresPermissions("deedTax:deedTaxPrint")
    public void deedTaxPrint(HttpServletRequest request, ModelMap modelMap) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        int contractId = ParamUtils.getInt(request, "contractId", 0);
        Contract contract = this.contractService.findOne(contractId);
        Precondition.checkSqdsArguement(contract != null, "数据有误");
        CalculateUtils.main(contract.getId());
        List<String> careBuyAreaNameList = CareBuyAreaUtils.getCareBuyAreaNameList(contract);
        modelMap.addAttribute("careBuyAreaNameList", careBuyAreaNameList);
        modelMap.addAttribute("contract", contract);
    }

    /**
     * 保存面积单价
     *
     * @param request
     */
    @RequestMapping("setDeedTaxPrice")
    @ResponseBody
    @RequiresPermissions("deedTax:setDeedTaxPrice")
    public synchronized Response setDeedTaxPrice(HttpServletRequest request) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Integer contractId = ParamUtils.getInt(request, "contractId", 0);
        Contract contract = this.contractService.findOne(contractId);
        Precondition.checkAjaxArguement(contract != null, "1111", "数据错误！");
        WebUtils.bind(request, contract);
        this.contractService.save(contract);
        CalculateUtils.main(contract.getId());
        return new Response("0001", "保存成功!");
    }

    /**
     * 税费什么列表
     */
    @RequestMapping("deedShList")
    @RequiresPermissions("deedTax:deepShList")
    public void deepShList() {
    }

    /**
     * 加载税费审核数据
     *
     * @return
     */
    @RequestMapping("loadDeedShList")
    @ResponseBody
    @RequiresPermissions("deedTax:loadDeepShList")
    public Map loadDeepShList(HttpServletRequest request) {
        List<Map> listData = Lists.newArrayList();
        String azProjectName = ParamUtils.getString(request, "azProjectName", "");
        PageBean<Contract> contractPageBean = this.contractService.getDeetListPageBean(azProjectName);
        List<Contract> contractList = contractPageBean.getDatas();
        Map<String, DataDict> signMap = this.dataDictService.getMapByParentNameForValue("签约状态");
        Map<String, DataDict> settleMap = this.dataDictService.getMapByParentNameForValue("财务结清状态");
        Map<String, DataDict> daffMap = this.dataDictService.getMapByParentNameForValue("档案发放状态");
        Map<String, DataDict> townMap = this.dataDictService.getMapByParentNameForValue("乡镇");
        Map<String, DataDict> deedShMap = this.dataDictService.getMapByParentNameForValue("税费审核情况");
        if (!CollectionUtils.isEmpty(contractList)) {
            Map<String, Object> item = null;
            for (Contract contract : contractList) {
                item = null;
                item = Maps.newHashMap();
                item.put("id", contract.getId());
                item.put("town", StringUtils.dataDictShow(townMap.get(contract.getZsProject().getTown())));
                item.put("zsProjectName", contract.getZsProject().getProjectName());
                item.put("contractCode", StringUtils.getNotNull(contract.getContractCode()));
                item.put("name", StringUtils.getNotNull(contract.getName()));
                item.put("chooseHouseNum", StringUtils.getNotNull(contract.getChooseHouseNum()));
                item.put("limitHouseAreaTotal", BigDecimalUtils.getNotNullStr(contract.getLimitHouseAreaTotal()));
                item.put("azSignStatus", IntegerUtils.getNotNull(contract.getAzSignStatus()));
                item.put("azSignStatusStr", StringUtils.dataDictShow(signMap.get(IntegerUtils.getNotNull(contract.getAzSignStatus()).toString())));
                item.put("financeSettleStatus", IntegerUtils.getNotNull(contract.getFinanceSettleStatus()));
                item.put("financeSettleStatusStr", StringUtils.dataDictShow(settleMap.get(IntegerUtils.getNotNull(contract.getFinanceSettleStatus()).toString())));
                item.put("daffStatus", IntegerUtils.getNotNull(contract.getDaffStatus()));
                item.put("daffStatusStr", StringUtils.dataDictShow(daffMap.get(IntegerUtils.getNotNull(contract.getDaffStatus()).toString())));
                item.put("deedShStatusStr", StringUtils.dataDictShow(deedShMap.get(IntegerUtils.getNotNull(contract.getDeedShStatus()).toString())));
                listData.add(item);
            }
        }
        return LayUiUtils.page(contractPageBean.getTotalCount().intValue(), listData);
    }


    /**
     * 税费审核信息查看
     *
     * @param request
     * @param modelMap
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    @RequestMapping("deedShPrint")
    @RequiresPermissions("deedTax:deedShPrint")
    public void deedShPrint(HttpServletRequest request, ModelMap modelMap) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        int contractId = ParamUtils.getInt(request, "contractId", 0);
        Map<String, DataDict> deedShMap = this.dataDictService.getMapByParentNameForValue("税费审核情况");
        Contract contract = this.contractService.findOne(contractId);
        Precondition.checkSqdsArguement(contract != null, "数据有误");
        List<House> houseList = new ArrayList<>();
        List<CarLot> carLotList = new ArrayList<>();
        List<StorageRoom> storageRoomList = new ArrayList<>();
        houseList = this.houseService.getHouseListByContractId(contract.getId());
        carLotList = this.carLotService.getCarLotListByContractId(contract.getId());
        storageRoomList = this.storageRoomService.getStorageRoomListByContractId(contract.getId());
        Map<String, List<Map>> buyHousePersonHouseMap = this.buyHousePersonService.getBuyHousePersonByHouse();
        Map<String, List<Map>> buyHousePersonCarLotMap = this.buyHousePersonService.getBuyHousePersonByCarLot();
        Map<String, List<Map>> buyHousePersonStorageRoomMap = this.buyHousePersonService.getBuyHousePersonByStorageRoom();

        modelMap.addAttribute("contract", contract);
        modelMap.addAttribute("houseList", houseList);
        modelMap.addAttribute("carLotList", carLotList);
        modelMap.addAttribute("deedShMap", deedShMap);
        modelMap.addAttribute("storageRoomList", storageRoomList);
        modelMap.addAttribute("buyHousePersonHouseMap", buyHousePersonHouseMap);
        modelMap.addAttribute("buyHousePersonCarLotMap", buyHousePersonCarLotMap);
        modelMap.addAttribute("buyHousePersonStorageRoomMap", buyHousePersonStorageRoomMap);
    }

    /**
     * 房源信息导出
     */
    @RequestMapping("deedTaxExcel1")
    @RequiresPermissions("deedTax:deedTaxExcel1")
    public void deedTaxExcel1(HttpServletRequest request, HttpServletResponse response) {
        int contractId = ParamUtils.getInt(request, "contractId", 0);
        Contract contract = this.contractService.findOne(contractId);
        Precondition.checkSqdsArguement(contract != null, "数据有误！");

        List<House> houseList = this.houseService.getHouseListNoSpByContractId(contractId);
        List<StorageRoom> storageRoomList = this.storageRoomService.getStorageRoomListByContractId(contractId);
        List<CarLot> carLotList = this.carLotService.getCarLotListByContractId(contractId);

        Map<String, List<Map>> buyHousePersonHouseMap = this.buyHousePersonService.getBuyHousePersonByHouse();
        Map<String, List<Map>> buyHousePersonCarLotMap = this.buyHousePersonService.getBuyHousePersonByCarLot();
        Map<String, List<Map>> buyHousePersonStorageRoomMap = this.buyHousePersonService.getBuyHousePersonByStorageRoom();


        try {
            // 封装导出数据
            Map data = Maps.newHashMap();
            data.put("contract", contract);
            data.put("houseList", houseList);
            data.put("storageRoomList", storageRoomList);
            data.put("carLotList", carLotList);
            List<Map> mapList = AreaAndPriceUtils.getAreaAndPriceList(contract);

            data.put("areaList", mapList);
            data.put("areaListLengh", mapList.size());
            data.put("size", mapList.size() + 5 > 8 ? mapList.size() + 5 : 9);

            data.put("bigUtils", new BigDecimalUtils());
            data.put("intUtils", new IntegerUtils());
            data.put("strUtils", new StringUtils());

            data.put("buyHousePersonHouseMap", buyHousePersonHouseMap);
            data.put("buyHousePersonCarLotMap", buyHousePersonCarLotMap);
            data.put("buyHousePersonStorageRoomMap", buyHousePersonStorageRoomMap);
            data.put("exportPerson", SecurityUtils.getSubject().getPrincipal());   //导出人姓名
            data.put("exportTime", DateUtils.dateToStringFormat(new Date(), "yyyy-MM-dd HH:mm:ss"));   //导出时间
//            data.put("decisions", exportDecisionList); //第二个worksheet的数据对象
            request.setCharacterEncoding("UTF-8");
            response.setContentType("application/x-download;");
            response.setHeader("Content-disposition", "attachment; filename=" + new String(("计收契税明细表.xls").getBytes(), "iso-8859-1"));
            freemarkerConfiguration.getTemplate("/business/property/deedTax/deedTaxExcel1.ftl").process(data, response.getWriter());
        } catch (Exception e) {
            logger.error("文件下载异常", e);
            e.printStackTrace();
        }
    }

    /**
     * 房源信息导出
     */
    @RequestMapping("deedTaxExcel2")
    @RequiresPermissions("deedTax:deedTaxExcel2")
    public void deedTaxExcel2(HttpServletRequest request, HttpServletResponse response) {
        int contractId = ParamUtils.getInt(request, "contractId", 0);
        Contract contract = this.contractService.findOne(contractId);
        List<House> houseList = this.houseService.getHouseListNoSpByContractId(contractId);
        List<StorageRoom> storageRoomList = this.storageRoomService.getStorageRoomListByContractId(contractId);
        List<CarLot> carLotList = this.carLotService.getCarLotListByContractId(contractId);

        Map<String, List<Map>> buyHousePersonHouseMap = this.buyHousePersonService.getBuyHousePersonByHouse();
        Map<String, List<Map>> buyHousePersonCarLotMap = this.buyHousePersonService.getBuyHousePersonByCarLot();
        Map<String, List<Map>> buyHousePersonStorageRoomMap = this.buyHousePersonService.getBuyHousePersonByStorageRoom();

        String azProjectNamelistStr = this.buyHousePersonService.azProjectName(contractId);

        try {
            // 封装导出数据
            Map data = Maps.newHashMap();
            data.put("contract", contract);
            data.put("azProjectNamelistStr", azProjectNamelistStr);
            data.put("houseList", houseList);
            data.put("storageRoomList", storageRoomList);
            data.put("carLotList", carLotList);
            List<Map> mapList = AreaAndPriceUtils.getAreaAndPriceList(contract);

            data.put("size", houseList.size() + storageRoomList.size() + carLotList.size());

            data.put("bigUtils", new BigDecimalUtils());
            data.put("intUtils", new IntegerUtils());
            data.put("strUtils", new StringUtils());
            data.put("dateUtils", new DateUtils());

            data.put("buyHousePersonHouseMap", buyHousePersonHouseMap);
            data.put("buyHousePersonCarLotMap", buyHousePersonCarLotMap);
            data.put("buyHousePersonStorageRoomMap", buyHousePersonStorageRoomMap);
            data.put("exportPerson", SecurityUtils.getSubject().getPrincipal());   //导出人姓名
            data.put("exportTime", DateUtils.dateToStringFormat(new Date(), "yyyy-MM-dd HH:mm:ss"));   //导出时间
//            data.put("decisions", exportDecisionList); //第二个worksheet的数据对象
            request.setCharacterEncoding("UTF-8");
            response.setContentType("application/x-download;");
            response.setHeader("Content-disposition", "attachment; filename=" + new String(("计收契税明细表.xls").getBytes(), "iso-8859-1"));
            freemarkerConfiguration.getTemplate("/business/property/deedTax/deedTaxExcel2.ftl").process(data, response.getWriter());
        } catch (Exception e) {
            logger.error("文件下载异常", e);
            e.printStackTrace();
        }
    }


    /**
     * 设置协议税费审核状态（可撤销）
     *
     * @param request
     */
    @RequestMapping("setDeedShStatus")
    @ResponseBody
    @RequiresPermissions("deedTax:setDeedShStatus")
    public synchronized Response setDeedShStatus(HttpServletRequest request) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Integer contractId = ParamUtils.getInt(request, "contractId", 0);
        String str = null;
        Contract contract = this.contractService.findOne(contractId);
        Precondition.checkAjaxArguement(contract != null, "1111", "数据错误！");
        if (contract.getDeedShStatus().equals(Status.NO.getIndex()) || contract.getDeedShStatus().equals(Status.TUI.getIndex())) {
            contract.setDeedShStatus(Status.YES.getIndex());
            contract.setDeedShDate(new Date());
            str = "设置该户税费已审核";
        } else if (contract.getDeedShStatus().equals(Status.YES.getIndex())) {
            contract.setDeedShStatus(Status.NO.getIndex());
            contract.setDeedShDate(null);
            str = "设置该户税费未审核";
        }
        this.contractService.save(contract);
        //该协议下所有房源、车位、储物间设置为税费已审核
        this.contractService.setDeedStatusSh(contract);

        return new Response("0001", "操作成功");
    }

    /**
     * 房屋  税费单项审核
     *
     * @param request
     * @return
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    @RequestMapping("setHouseDeedShStatus")
    @ResponseBody
    @RequiresPermissions("deedTax:setHouseDeedShStatus")
    public synchronized Response setHouseDeedShStatus(HttpServletRequest request) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Integer houseId = ParamUtils.getInt(request, "houseId", 0);
        String str = null;
        House house = this.houseService.findOne(houseId);
        Contract contract = this.contractService.findOne(house.getContract().getId());
        Precondition.checkAjaxArguement(house != null, "1111", "数据错误！");
        if (house.getDeedShStatus().equals(Status.NO.getIndex())) {
            house.setDeedShStatus(Status.YES.getIndex());
            house.setDeedShDate(new Date());
            str = "设置该户税费已审核";
        } else if (house.getDeedShStatus().equals(Status.YES.getIndex())) {
            house.setDeedShStatus(Status.NO.getIndex());
            house.setDeedShDate(null);
            str = "设置该户税费未审核";

        }
        this.houseService.save(house);
        this.contractService.setDeedShStatusByItem(contract);
        return new Response("0001", "操作成功");
    }

    /**
     * 车位  税费单项审核
     *
     * @param request
     * @return
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    @RequestMapping("setCarLotDeedShStatus")
    @ResponseBody
    @RequiresPermissions("deedTax:setCarLotDeedShStatus")
    public synchronized Response setCarLotDeedShStatus(HttpServletRequest request) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Integer carLotId = ParamUtils.getInt(request, "carLotId", 0);
        String str = null;
        CarLot carLot = this.carLotService.findOne(carLotId);
        Precondition.checkAjaxArguement(carLot != null, "1111", "数据错误！");
        Contract contract = this.contractService.findOne(carLot.getContract().getId());
        if (carLot.getDeedShStatus().equals(Status.NO.getIndex())) {
            carLot.setDeedShStatus(Status.YES.getIndex());
            carLot.setDeedShDate(new Date());
            str = "设置该户税费已审核";
        } else if (carLot.getDeedShStatus().equals(Status.YES.getIndex())) {
            carLot.setDeedShStatus(Status.NO.getIndex());
            carLot.setDeedShDate(null);
            str = "设置该户税费未审核";
        }
        this.carLotService.save(carLot);
        this.contractService.setDeedShStatusByItem(contract);
        return new Response("0001", "操作成功");
    }

    /**
     * 储藏间 税费单项审核
     *
     * @param request
     * @return
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    @RequestMapping("setStorageRoomDeedShStatus")
    @ResponseBody
    @RequiresPermissions("deedTax:setStorageRoomDeedShStatus")
    public synchronized Response setStorageRoomDeedShStatus(HttpServletRequest request) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Integer storageRoomId = ParamUtils.getInt(request, "storageRoomId", 0);
        String str = null;
        StorageRoom storageRoom = this.storageRoomService.findOne(storageRoomId);
        Precondition.checkAjaxArguement(storageRoom != null, "1111", "数据错误！");
        Contract contract = this.contractService.findOne(storageRoom.getContract().getId());
        if (storageRoom.getDeedShStatus().equals(Status.NO.getIndex())) {
            storageRoom.setDeedShStatus(Status.YES.getIndex());
            storageRoom.setDeedShDate(new Date());
            str = "设置该户税费已审核";
        } else if (storageRoom.getDeedShStatus().equals(Status.YES.getIndex())) {
            storageRoom.setDeedShStatus(Status.NO.getIndex());
            storageRoom.setDeedShDate(null);
            str = "设置该户税费未审核";

        }
        this.storageRoomService.save(storageRoom);
        this.contractService.setDeedShStatusByItem(contract);
        return new Response("0001", "操作成功");
    }


}
